<!-- 本DEMO演示FocusNext功能 -->
<template>
  <q-page class="q-pa-md">
    <div class="q-pb-md text-h5">Auto Focus <span class="text-subtitle1">回车聚焦下一个的演示</span></div>
    <div class="shadow-2 q-pa-sm">
      <div class="row">
        <div class="col-12 shadow-2 q-pa-sm">
          <p>
            <code>focus-next-on-enter</code>是我给之前的前端框架写的一个directive，能很轻松实现按回车调到下一个的功能，
            但到了vue3，directive就不能轻易获取到组件的实例(instance)，使得开发这个directive遇到了很大的障碍，这恐怕是从
            vue2到vue3迁移的最大的障碍之一了。最终用一个hooks来实现，用起来比原先的略繁琐，但总算功能是出来了。下面是DEMO说明。
          </p>
          <ul class="q-ma-xs">
            <li>上方蓝色框
              <q-icon name="crop_landscape" style="color:#00F8" size="20px" />
              表示组件之前的输入区域
            </li>
            <li>绿色框
              <q-icon name="crop_landscape" style="color:#0F08" size="20px" />
              表示组件自带的输入区域
            </li>
            <li>红色框
              <q-icon name="crop_landscape" style="color:#F008" size="20px" />
              表示组件的插槽的输入区域
            </li>
            <li>下方紫红色框
              <q-icon name="crop_landscape" style="color:#F0F8" size="20px" />
              表示组件之后的输入区域
            </li>
          </ul>

          <p>根据实际需求，从上到下一个个focus过来，
            <q-icon name="crop_landscape" style="color:#00F8" size="20px" />
            使用一个hooks，
            <q-icon name="crop_landscape" style="color:#0F08" size="20px" />
            使用一个hooks，而
            <q-icon name="crop_landscape" style="color:#F008" size="20px" />
            和
            <q-icon name="crop_landscape" style="color:#F0F8" size="20px" />
            两个共用一个hooks。一共用了3个hooks。
          </p>

          <p>
            <q-icon name="crop_landscape" style="color:#00F8" size="20px" />在最后一个input按enter之后，
            通过回调函数调用组件暴露出来的<code>focusAtFirstInput</code>方法，使得组件的第一个input获得焦点; 组件最后一个input按enter之后，
            通过回调函数emit一个事件<code>on-last-entered</code>出来，通过这个事件调用<q-icon name="crop_landscape" style="color:#F008" size="20px" />
            和<q-icon name="crop_landscape" style="color:#F0F8" size="20px" />的hooks，使得插槽里的第一个input获得焦点。
          </p>

          <p>
            目前潜在的问题是q-select在按enter跳到下一个元素的时候，不能自动将其popup关闭起来，因为enter会触发q-select的popup的出现，这个Quasar没提供选项，下面的例子也有演示。
          </p>
        </div>
      </div>
      <div class="row">
        <q-toggle v-model="showOrHideTheComponent" color="primary">显示或隐藏组件</q-toggle>
      </div>
      <!-- regRef和onEntered的index参数不一定要从1开始，也不一定需要连续 -->
      <div style="border: 5px solid #00F8">
        <div class="row q-col-gutter-sm q-pt-sm">
          <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <span>前置字段1</span>
            <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="preField1"
              :ref="el=>focusHelperPre.regRef(el, 9)" @keyup.enter="focusHelperPre.onEntered(9)"></q-input>
          </div>
          <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <span>前置字段2</span>
            <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="preField2"
              :ref="el=>focusHelperPre.regRef(el, 10)" @keyup.enter="focusHelperPre.onEntered(10)">
            </q-input>
          </div>
          <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <span>前置字段3</span>
            <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="preField3"
              :ref="el=>focusHelperPre.regRef(el, 11)" @keyup.enter="focusHelperPre.onEntered(11)">
            </q-input>
          </div>
        </div>
      </div>

      <!--
      组件(实际上可能是一个页面)插槽里的input和本DEMO页的input都是本页的东西，focus-next-on-enter没有问题，
      但是组件内部的input(非插槽)和本页的input就没办法让focus-next-on-enter自动工作正常，只能手工来做这个事情，
      如这个DEMO，组件的input是出现在插槽input及本页input之前的，所以当组件在最后一个input上按了enter之后，
      触发一个事件，页面处理一下这个事件，然后手工地让插槽的第一个input获得焦点，这样就OK了

      如果本页的input出现在组件的input之前，那也得特殊处理，在本页最后一个input被enter的时候，调用组件的focusFirst方法，让组件第一个
      input获得焦点。
      -->
      <div style="border: 5px solid #0F08">
        <focus-next-test-component ref="theTestComponent" v-if="showOrHideTheComponent"
          @on-last-entered="onLastEnteredOfComponent">
          <div style="border:5px #F008 solid">
            <div class="row q-col-gutter-sm q-pt-sm">
              <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                <span>插槽字段1</span>
                <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="slotField1"
                  :ref="el=>focusHelper.regRef(el, 1)" @keyup.enter="focusHelper.onEntered(1)"></q-input>
              </div>
              <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                <span>插槽字段2</span>
                <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="slotField2"
                  :ref="el=>focusHelper.regRef(el, 2)" @keyup.enter="focusHelper.onEntered(2)">
                </q-input>
              </div>
              <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                <span>插槽字段3</span>
                <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="slotField3"
                  :ref="el=>focusHelper.regRef(el, 3)" @keyup.enter="focusHelper.onEntered(3)">
                </q-input>
              </div>
            </div>
          </div>
        </focus-next-test-component>
      </div>
      <div style="border: 5px solid #F0F8">
        <div class="row q-col-gutter-sm q-pt-sm">
          <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <span>后继字段1</span>
            <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="postField1"
              :ref="el=>focusHelper.regRef(el, 4)" @keyup.enter="focusHelper.onEntered(4)"></q-input>
          </div>
          <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <span>后继字段2</span>
            <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="postField2"
              :ref="el=>focusHelper.regRef(el, 5)" @keyup.enter="focusHelper.onEntered(5)">
            </q-input>
          </div>
          <div class="col-12 col-sm-6 col-md-4 col-lg-3">
            <span>后继字段3</span>
            <q-input :hide-bottom-space="true" dense outlined square stack-label v-model="postField3"
              :ref="el=>focusHelper.regRef(el, 6)" @keyup.enter="focusHelper.onEntered(6)">
            </q-input>
          </div>
        </div>
      </div>
    </div>
  </q-page>
</template>

<script lang="ts" setup>
import {ref} from 'vue'
import {useFocusNextHelper} from '../../lib/hooks/focusHelper'
import focusNextTestComponent from 'components/FocusNextTestComponent.vue'

let showOrHideTheComponent = ref(true)
let slotField1 = ref('')
let slotField2 = ref('')
let slotField3 = ref('')

let preField1 = ref('')
let preField2 = ref('')
let preField3 = ref('')

let postField1 = ref('')
let postField2 = ref('')
let postField3 = ref('')

let onLastEnteredOfComponent = function () {
  focusHelper.focusFirst()
}

const theTestComponent = ref()

// 前置，这个写起来挺难看，但想不到更好的办法了
const focusHelperPre = useFocusNextHelper(() => {
  if (theTestComponent.value) {
    theTestComponent.value.focusAtFirstInput()
  } else {
    focusHelper.focusFirst()
  }
})

// 插槽及后继(正常取这个名字即可"focusHelper")
const focusHelper = useFocusNextHelper()

</script>

<style lang="sass" scoped>
code
  background-color: #EEE

p
  margin: 5px
</style>
